using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#if XBOX
#else
using System.Windows;
#endif

namespace Perovich.GameObjects.Controls
{

    #if XBOX
    public enum VerticalAlignment
    {
        Top,
        Center,
        Bottom,
        Stretch
    }

    public enum HorizontalAlignment
    {
        Left,
        Center,
        Right,
        Stretch
    }


    public struct Thickness : IEquatable<Thickness>
    {

        #region IEquatable<Thickness> Members

        public bool Equals(Thickness other)
        {
            return ((this.Top == other.Top) &&
                (this.Bottom == other.Bottom) &&
                (this.Left == other.Left) &&
                (this.Right == other.Right));
        }

        #endregion

        public Thickness(double uniformLength)
        {
            bottom = uniformLength;
            left = uniformLength;
            right = uniformLength;
            top = uniformLength;
        }

        public Thickness(double left, double top, double right, double bottom)
        {
            this.left = left;
            this.top = top;
            this.right = right;
            this.bottom = bottom;
        }

        public override bool Equals(object obj)
        {
            Thickness? ob;
            if ((ob = obj as Thickness?) != null)
                return Equals(ob);
            else
                return false;
        }

        public override int GetHashCode()
        {
            double total = Left + Right + Bottom + Top;
            byte[] b = BitConverter.GetBytes(total);
            return BitConverter.ToInt32(b, 0) + BitConverter.ToInt32(b, 4);
        }

        public override string ToString()
        {
            return string.Format("Left:{0} Right:{1} Top:{2} Bottom:{3}", Left, Right, Top, Bottom);
        }

        public static bool operator ==(Thickness a,Thickness b)
        {
            return a.Equals(b);
        }

        public static bool operator !=(Thickness a, Thickness b) {
            return !(a == b);
        }

        double bottom;
        double left;
        double right;
        double top;

        public double Bottom
        {
            get
            {
                return bottom;
            }
        }

        public double Left
        {
            get
            {
                return left;
            }
        }

        public double Right
        {
            get
            {
                return right;
            }
        }

        public double Top
        {
            get
            {
                return top;
            }
        }
    }


    #endif
    /// <summary>
    /// The <see cref="Control"/> class is an abstract base class for any components that are to act like GUI controls.
    /// </summary>
    public abstract class Control : GameObject
    {
        

        private Color _fore;

        /// <summary>
        /// Gets or sets the <see cref="Color"/> any foreground elements of this <see cref=" Control"/> will be drawn in.
        /// </summary>
        public Color ForegroundColor
        {
            get
            {
                return _fore;
            }
            set
            {
                Color old = _fore;
                _fore = value;
                if ((ForegroundColorChanged != null) && (_fore != old))
                    ForegroundColorChanged(this, null);
            }
        }

        private Color _back;

        /// <summary>
        /// Gets or sets the <see cref="Color"/> any background elements of this <see cref=" Control"/> will be drawn in.
        /// </summary>
        public Color BackgroundColor
        {
            get
            {
                return _back;
            }
            set
            {
                Color old = _back;
                _back = value;
                if ((BackgroundColorChanged != null) && (_back != old))
                    BackgroundColorChanged(this, null);
            }
        }

        /// <summary>
        /// Triggered when the <see cref="ForegroundColor"/> property is changed.
        /// </summary>
        public event EventHandler ForegroundColorChanged;
        /// <summary>
        /// Triggered when the <see cref="BackgroundColor"/> property is changed.
        /// </summary>
        public event EventHandler BackgroundColorChanged;

        private float _width;

        /// <summary>
        /// Gets or sets the desired width of this <see cref="Control"/> in pixels.
        /// </summary>
        public float Width
        {
            get
            {
                return _width;
            }
            set
            {
                float old = _width;
                _width = value;
                if ((WidthChanged != null)&&(_width != old))
                    WidthChanged(this, null);
            }
        }

        private float _height;

        /// <summary>
        /// Gets or sets the desired height of this <see cref="Control"/> in pixels.
        /// </summary>
        public float Height
        {
            get
            {
                return _height;
            }
            set
            {
                float old = _height;
                _height = value;
                if ((HeightChanged != null)&&(_height != old))
                    HeightChanged(this, null);
            }
        }

        /// <summary>
        /// Triggered when the <see cref="Control.Height"/> property is changed.
        /// </summary>
        public event EventHandler HeightChanged;

        /// <summary>
        /// Triggered when the <see cref="Control.Width"/> property is changed.
        /// </summary>
        public event EventHandler WidthChanged;


        private Thickness _margin;

        /// <summary>
        /// Gets or sets the margin arround this <see cref="Control"/>.
        /// </summary>
        public Thickness Margin
        {
            get
            {
                return _margin;
            }
            set
            {
                _margin = value;
                if (MarginChanged != null)
                    MarginChanged(this, null);
            }
        }

        /// <summary>
        /// Triggered when the <see cref="Control.Margin"/> is changed.
        /// </summary>
        public event EventHandler MarginChanged;

        private Vector2 _position;




        private float _rotation;

        /// <summary>
        /// Gets or sets the rotation of this <see cref="Control"/> in radians.
        /// </summary>
        public float Rotation
        {
            get { return _rotation; }
            set
            {
                float old = _rotation;
                _rotation = value;
                if (_rotation != old)
                    SignalRotationChanged();
            }
        }

        /// <summary>
        /// Triggered when the <see cref="Rotation"/> property changes.
        /// </summary>
        public event EventHandler RotationChanged;

        void SignalRotationChanged()
        {
            if (RotationChanged != null)
            {
                RotationChanged(this, null);
            }
        }


        /// <summary>
        /// Gets or sets the position of this <see cref="Control"/>.
        /// </summary>
        public Vector2 Position
        {
            get { return _position; }
            set { _position = value; }
        }


        /// <summary>Initializes a new <see cref="Control"/>.</summary>
        /// <param name="game">
        ///   <see cref="Perovich.GameObjects.Interfaces.ICanHoldComponents"/> instance that this <see cref="Control"/> will be constructed for.
        /// </param>
        protected Control(Interfaces.ICanHoldComponents game)
            : base(game)
        {
            _position = Vector2.Zero;
            Width = 0;
            Height = 0;
            ForegroundColor = Color.Transparent;
            BackgroundColor = Color.Transparent;
            Margin = new Thickness();
            Active = true;
            Rotation = 0;
        }


    }

}
